﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Automation;

namespace QuickUIT
{
    /// <summary>
    /// Represents an automation element search criteria where all conditions must be true for a match.  
    /// </summary>
    public class AutomationElementSearchCriteria : IAutomationElementSearchCriteria
    {
        private readonly List<IAutomationElementSearchCondition> _conditions = new List<IAutomationElementSearchCondition>();

        /// <summary>
        /// Gets or sets the zero-based index for selecting an <see cref="AutomationElement"/> from a set of search results.
        /// Ignored if less than zero. 
        /// </summary>
        public int Index { get; set; }

        /// <summary>
        /// Initializes a new <see cref="AutomationElementSearchCriteria"/>
        /// </summary>
        public AutomationElementSearchCriteria()
        {
            Index = -1; 
        }

        /// <summary>
        /// Gets a list of all search criteria search conditions.   
        /// </summary>
        public IList<IAutomationElementSearchCondition> Conditions
        {
            get { return _conditions; } 
        }

        /// <summary>
        /// Adds a search condition to the search criteria.
        /// </summary>
        /// <param name="condition">The search condition to add.</param>
        public void Add(IAutomationElementSearchCondition condition)
        {
            _conditions.Add(condition); 
        }

        /// <summary>
        /// Adds a search condition to the search criteria with the specified priority.
        /// </summary>
        /// <param name="condition">The search condition to add.</param>
        /// <param name="priority">The priority of the search condition.</param>
        public void Add(IAutomationElementSearchCondition condition, int priority)
        {
            if (priority == 0)
            {
                _conditions.Insert(0, condition);
            }
            _conditions.Add(condition);
        }
        
        /// <summary>
        /// Indicates whether an <see cref="AutomationElement"/> matches the specified search criteria.   
        /// </summary>
        /// <param name="element">The element to match.</param>
        /// <returns>True if the element satisified the search criteria; otherwise, false.</returns>
        public bool Matches(AutomationElement element)
        {
            foreach (var condition in _conditions)
            {
                if (!condition.Matches(element)) return false;
            }
            return true;
        }

        /// <summary>
        /// Returns a string that represents the current object.
        /// </summary>
        /// <returns>A string that represents the current object.</returns>
        public override string ToString()
        {
            var stringBuilder = new StringBuilder();
            foreach (var condition in _conditions)
            {
                stringBuilder.Append(String.Format("[{0}]", condition)); 
            }
            if (Index >= 0)
            {
                stringBuilder.Append(String.Format("[{0}]", Index)); 
            }
            return stringBuilder.ToString(); 
        }
    }
}
